/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.yonsei.iwb.srf.classifier;

import edu.yonsei.iwb.sdt.datastructure.DecomposeCandidate;
import edu.yonsei.iwb.sdt.datastructure.DecomposeCandidateSet;
import edu.yonsei.iwb.sdt.datastructure.TargetInstance;
import edu.yonsei.iwb.sdt.datastructure.tree.BranchingType;
import edu.yonsei.iwb.sdt.ontology.PropertyArc;
import edu.yonsei.iwb.sdt.refinement.CardinalityRestrictionRefinement;
import edu.yonsei.iwb.sdt.refinement.DLConstructors;
import edu.yonsei.iwb.sdt.refinement.ExpandingHistory;
import edu.yonsei.iwb.sdt.refinement.ExpandingHistorySet;
import edu.yonsei.iwb.sdt.refinement.Refinement;
import edu.yonsei.iwb.sdt.refinement.RefinementType;
import edu.yonsei.iwb.ts.TSSearch;
import edu.yonsei.iwb.ts.model.ObjectNode;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

/**
 *
 * @author dk
 */
public class CardinalityRestrictionRefinementClassifier {

    public Vector<String> satisfiedSet(Vector<String> insset, PropertyArc pa, int standard) throws IOException {
        Hashtable<String, Integer> valueNumTable = this.getBaseValueNumberTable(pa);
        Vector<String> resultset = new Vector();

        for (int i = 0; i < insset.size(); i++) {
            String ins = insset.get(i);
            try {
                int number = valueNumTable.get(ins);
                if (number > standard) {
                    resultset.add(ins);
                }
            } catch (NullPointerException npe) {
            }
        }
        return resultset;
    }

    public Vector<String> satisfiedSet(Vector<String> insset, PropertyArc pa, int standard, Vector<PropertyArc> pset, Vector<String> qset) throws IOException {
        Vector<String> resultset = new Vector();
        Hashtable<String, Integer> valueNumTable = this.getBaseValueNumberTable(pa);
        QuantificationRefinementClassifier qrc = new QuantificationRefinementClassifier();
        
        Vector<String> hisinsset = this.getStandardSatisfiedInstanceSet(valueNumTable, standard);
        
        for (int i = pset.size() - 1; i > -1; i--) {
            PropertyArc hisp = pset.get(i);
            Hashtable<String,ArrayList<String>> pastrset = qrc.getPastResAndValueTable(hisp);           
            String quantifier = qset.get(i);
            if (quantifier.equals(DLConstructors.EXISTENTIAL)) {
                hisinsset = qrc.getExistentialResources(hisinsset, hisp, pastrset);
            } else {
                hisinsset = qrc.getUniversalResources(hisinsset, hisp, pastrset);
            }
        }
                        
        for (int i = 0; i < hisinsset.size(); i++) {
            String ins = hisinsset.get(i);
            if(insset.contains(ins)){
                resultset.add(ins);
            }            
        }

        return resultset;
    }

    private Vector<String> getStandardSatisfiedInstanceSet(Hashtable<String, Integer> valueNumTable, int standard) {
        Vector<String> result = new Vector();
        Enumeration<String> values = valueNumTable.keys();
        while (values.hasMoreElements()) {
            String value = values.nextElement();
            int size = valueNumTable.get(value);
            if (size > standard) {
                result.add(value);
            }
        }
        return result;
    }

    private Hashtable<String, Integer> getBaseValueNumberTable(PropertyArc pa) throws IOException {
        Hashtable<String, Integer> valueNumTable = new Hashtable();

        if (pa.getDirection()) {
            ArrayList<String> res = TSSearch.listSubjectResource(pa.getProperty());
            for (int i = 0; i < res.size(); i++) {
                String value = res.get(i);
                if (!valueNumTable.containsKey(value)) {
                    valueNumTable.put(value, 1);
                } else {
                    int size = valueNumTable.get(value);
                    size++;
                    valueNumTable.put(value, size);
                }
            }
        } else {
            ArrayList<ObjectNode> ni = TSSearch.listObjectNode(pa.getProperty());
            for (int i = 0; i < ni.size(); i++) {
                ObjectNode on = ni.get(i);
                String value = on.getValue();
                if (!valueNumTable.containsKey(value)) {
                    valueNumTable.put(value, 1);
                } else {
                    int size = valueNumTable.get(value);
                    size++;
                    valueNumTable.put(value, size);
                }
            }
        }
        return valueNumTable;
    }
}
